﻿// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Admin.NET.Application.Entity;
using Admin.NET.Application.Service.Tray.Dto;
using Admin.NET.Application.Service.Warehouse;
using Furion.Logging;
using System.Data;

namespace Admin.NET.Application.Service.Tray;
/// <summary>
/// 出入口
/// </summary>
[ApiDescriptionSettings(groups: ApplicationConst.GroupName, Order = 12)]

public class EntranceAndexitService : IDynamicApiController
{
    private readonly SqlSugarRepository<EntranceAndexitEntity> _entranceAndexitEntity;

    //private readonly SqlSugarRepository<TrayEntity> _entranceAndexitEntity;
    private readonly UserManager _userinfo;
    private readonly IHttpContextAccessor _accessor;


    public EntranceAndexitService(SqlSugarRepository<EntranceAndexitEntity> entranceAndexitEntity, UserManager userinfo, IHttpContextAccessor accessor)
    {
        _userinfo = userinfo;
        _accessor = accessor;
        _entranceAndexitEntity = entranceAndexitEntity;

    }

    /// <summary>
    /// 获取出入口列表🔖
    /// </summary>
    /// <param name="andexitDto"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "GetEntranceAndexitPageList"), HttpPost]
    public async Task<SqlSugarPagedList<EntranceAndexitEntity>> GetEntranceAndexitPageList(EntranceAndexitDto andexitDto)
    {
        //var list = await _entranceAndexitEntity.AsQueryable()
        //       .Where(u =>
        //            (!string.IsNullOrWhiteSpace(andexitDto.Opening) && u.Opening == andexitDto.Opening) ||
        //            (!string.IsNullOrWhiteSpace(andexitDto.WarehousCode) && u.WarehousCode.Contains(andexitDto.WarehousCode))
        //        )
        //       .OrderBy(u => u.UpdateTime, OrderByType.Desc)
        //       .ToPagedListAsync(andexitDto.Page, andexitDto.PageSize);
        var list = await _entranceAndexitEntity.AsQueryable()
         .WhereIF(!string.IsNullOrWhiteSpace(andexitDto.Opening), u => u.Opening.Contains(andexitDto.Opening.Trim()))
         .WhereIF(!string.IsNullOrWhiteSpace(andexitDto.WarehousCode), u => u.WarehousCode.Contains(andexitDto.WarehousCode.Trim()))
         .WhereIF(!string.IsNullOrWhiteSpace(andexitDto.Poiint), u => u.WarehousCode.Contains(andexitDto.Poiint.Trim()))
            .OrderBy(u => u.CreateTime, OrderByType.Desc)
            .ToPagedListAsync(andexitDto.Page, andexitDto.PageSize);

        return list;
    }

    /// <summary>
    /// 获取订单信息 🔖
    /// </summary>
    /// <param name="andexitDto"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "GetEntranceAndexitList"), HttpPost]
    public async Task<List<EntranceAndexitEntity>> GetEntranceAndexitList(EntranceAndexitDto andexitDto)
    {
        Expression<Func<EntranceAndexitEntity, bool>> expression = whereExp =>
                 (andexitDto.Opening.GetIsEmptyOrNull() || whereExp.Opening.Contains((andexitDto.Opening.Trim())))
                 && (andexitDto.WarehousCode.GetIsEmptyOrNull() || whereExp.WarehousCode.Contains((andexitDto.WarehousCode.Trim())))
                 && (andexitDto.Poiint.GetIsEmptyOrNull() || whereExp.WarehousCode.Contains((andexitDto.Poiint.Trim())));
        //&& (andexitDto.WarehousCode.GetIsEmptyOrNull() || whereExp.WarehousCode.Contains((andexitDto.WarehousCode)));



        var list = await _entranceAndexitEntity.AsQueryable().WhereIF(expression != null, expression).ToListAsync();
        return list;
    }

    /// <summary>
    /// 添加出入口
    /// </summary>
    /// <param name="EntranceAndexitDto"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "EntranceAndexitAdd"), HttpPost]

    public async Task<long> EntranceAndexitAdd(AddEntranceAndexitInput EntranceAndexitDto)
    {
        Expression<Func<EntranceAndexitEntity, bool>> whereExpression = whereExp =>
                   whereExp.Id.Equals(EntranceAndexitDto.Id)
                   && whereExp.Opening.Equals(EntranceAndexitDto.Opening)
              ;
        var data = await _entranceAndexitEntity.GetFirstAsync(whereExpression);
        if (data != null)
        {
            throw Oops.Oh(10001, "该记录已存在");
        }
        var entity = EntranceAndexitDto.Adapt<EntranceAndexitEntity>();
        if (string.IsNullOrWhiteSpace(EntranceAndexitDto.Opening))
        {
            throw Oops.Oh("出入口不能为空");
        }
        await _entranceAndexitEntity.AsInsertable(entity).ExecuteCommandAsync();
        return entity.Id;
    }

    /// <summary>
    /// 修改出入口位
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "EntranceAndexitUpdate"), HttpPost]

    public async Task EntranceAndexitUpdate(EntranceAndexitEntity entity)
    {
        var EntranceAndexit = await _entranceAndexitEntity.GetFirstAsync(u => u.Id == entity.Id);

        try
        {
            if (EntranceAndexit != null)
            {
                if (entity != null)
                {

                    //对实体进行赋值
                    entity.UpdateUserId = _userinfo.UserId;
                    entity.UpdateTime = DateTime.Now;
                    entity.UpdateUserName = _userinfo.RealName;
                }
                else
                {
                    throw Oops.Oh("数据查询不到");
                }



            }
        }
        catch (Exception error)
        {
            Log.Information("UpdateEntranceAndexit", error.StackTrace);
            throw Oops.Oh("修改出入口出现错误：" + error.Message + "");
        }
        //api已转为entity
        var updateEntity = entity.Adapt<EntranceAndexitEntity>();

        await _entranceAndexitEntity.AsUpdateable(updateEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();

    }
    /// <summary>
    /// 批量删除
    /// </summary>
    /// <param name="inputList"></param>
    /// <returns></returns>
    [UnitOfWork]
    [ApiDescriptionSettings(Name = "BatchDeleteEntranceAndexit"), HttpDelete]
    [DisplayName("批量删除")]
    public virtual async Task<int> BatchDeleteEntranceAndexit(List<DeleteEntranceAndexitDtoInput> inputList)
    {
        #region "校验"
        foreach (var input in inputList)
        {
            Expression<Func<EntranceAndexitEntity, bool>> whereExpression = whereExp =>
                        whereExp.Id.Equals(input.Id)
                   ;
            var data = await _entranceAndexitEntity.GetFirstAsync(whereExpression);
            if (data == null)
            {
                throw Oops.Oh("该记录不存在");
            }

            // *****校验是否有其他表使用该记录*****
        }
        #endregion

        var deleteEntity = inputList.Adapt<List<EntranceAndexitEntity>>();
        return await _entranceAndexitEntity.AsDeleteable()
            .Where(deleteEntity)
            .ExecuteCommandAsync();
    }
    /// <summary>
    /// 删除出入口🔖
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "EntranceAndexitDelete"), HttpPost]
    [DisplayName("删除出入口")]
    public async Task EntranceAndexitDelete(DeleteEntranceAndexitDtoInput input)
    {
        #region "校验唯一索引"
        Expression<Func<EntranceAndexitEntity, bool>> whereExpression = whereExp =>
                    whereExp.Id.Equals(input.Id);
        #endregion    
        var entity = await _entranceAndexitEntity.GetFirstAsync(whereExpression) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        if (entity == null)
        {
            throw Oops.Oh("当前出入口数据不对");
        }
        else
        {
            await _entranceAndexitEntity.DeleteAsync(entity); // 假删除
            //await _rep.DeleteAsync(entity); // 真删除
        }
    }
    /// <summary>
    /// 下载模版
    /// </summary>
    /// <returns></returns>
    [UnitOfWork]
    [DisplayName("下载模版")]
    [ApiDescriptionSettings(Name = "DownloadEntranceAndexit"), HttpGet]
    public virtual async Task<IActionResult> DownloadEntranceAndexit()
    {
        #region "校验"
        string fileName = "EntranceAndexitTemplate.xlsx";
        string filePath = $"{AppDomain.CurrentDomain.BaseDirectory}/Template/{fileName}";
        if (!File.Exists(filePath))
        {
            throw Oops.Oh(10002, "找不到该模板：" + filePath);
        }
        #endregion

        var path = Path.Combine(filePath);
        return new FileStreamResult(new FileStream(path, FileMode.Open), System.Net.Mime.MediaTypeNames.Application.Octet)
        {
            FileDownloadName = fileName
        };
    }

    /// <summary>
    /// 导出出入口
    /// </summary>·
    [UnitOfWork]
    [DisplayName("导出出入口")]
    [ApiDescriptionSettings(Name = "EntranceAndexitExport"), HttpPost]
    public virtual async Task<IActionResult> EntranceAndexitExport(ExportEntranceAndexitInput input)
    {
        Expression<Func<EntranceAndexitEntity, bool>> whereExpression = whereExp =>
                   (input.WarehousCode.GetIsEmptyOrNull() || whereExp.WarehousCode.Equals(input.WarehousCode.Trim()))
                   && (input.Opening.GetIsEmptyOrNull() || whereExp.Opening.Contains(input.Opening.Trim()))
                   && (input.Point.GetIsEmptyOrNull() || whereExp.Point.Contains(input.Point.Trim()));


        var list = await _entranceAndexitEntity.AsQueryable()
           .WhereIF(whereExpression != null, whereExpression).OrderBuilder(input)
           .ToListAsync();
        string path = AppDomain.CurrentDomain.BaseDirectory + "Export";
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
        IExcelExporter excelExporter = new ExcelExporter();



        var res = await excelExporter.ExportAsByteArray(list);
        return new FileStreamResult(new MemoryStream(res), "application/octet-stream") { FileDownloadName = $"EntranceAndexitExport_{DateTime.Now.ToString("yyyyMMddHHmmss")}_{new Random().Next(10000000, 99999999)}.xlsx" };
    }


    /// <summary>
    /// 导入
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [UnitOfWork]
    [DisplayName("导入")]
    [ApiDescriptionSettings(Name = "ImportEntranceAndexit"), HttpPost]
    public virtual async Task<List<ImportEntranceAndexitOutput>> ImportEntranceAndexit([Required] IFormFile file)
    {

        if (file != null)
        {
            var fileDir = AppDomain.CurrentDomain.BaseDirectory + @"ImportFile";
            if (!Directory.Exists(fileDir))
            {
                Directory.CreateDirectory(fileDir);
            }
            //文件名称
            string fileName = file.FileName;
            //文件类型
            string fileType = file.FileName.Substring(fileName.LastIndexOf("."));
            //上传的文件的路径
            string filePath = fileDir + $@"/{fileName}";
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }
            using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                file.CopyTo(fs);
            }

            if (fileType == ".xlsx" || fileType == ".xls")
            {
                ExcelHelper eh = new ExcelHelper(filePath);
                DataTable dt = eh.ExcelToDataTable("", true);
                eh.Dispose();
                if (dt == null || dt.Rows.Count == 0)
                {
                    throw Oops.Oh("文件模板错误！请重新下载模板");
                }

                #region "校验模板字段"
                if (!dt.Columns.Contains("仓库代码") || !dt.Columns.Contains("出入口") || !dt.Columns.Contains("点位") || !dt.Columns.Contains("是否冻结"))
                {
                    throw Oops.Oh("文件模板错误！请重新下载模板");
                }
                #endregion

                List<ImportEntranceAndexitOutput> listLoad = new List<ImportEntranceAndexitOutput>();
                int i = 0;
                foreach (DataRow row in dt.Rows)
                {
                    i++;
                    // Fix for CS7036: Provide required parameters for WarehouseInfomationService constructor  
                    var warehouse = new WarehouseInfomationService(
                       new SqlSugarRepository<WarehouseEntity>(),
                       new SqlSugarRepository<WarehousePositionEntity>(),
                       _userinfo
                    );
                    var warehouseCodeList = await warehouse.GetWarehouseList(new Warehouse.Dto.WarehouseInput { Code = row["仓库代码"].GetCString(), Isenable = (WStatusEnum?)WStatusEnum.Enable });
                    if (warehouseCodeList.Count() < 1)
                    {
                        throw Oops.Oh($"文件内容填写出错！第{i}行仓库代码列没有{row["仓库代码"].GetCString()}请重新填写");

                    }

                    ImportEntranceAndexitOutput importPosition = new ImportEntranceAndexitOutput
                    {
                        #region "字段"
                        WarehousCode = row["仓库代码"].GetCString(),
                        Opening = row["出入口"].GetCString(),
                        Point = row["点位"].GetCString(),
                        // Update the Isenable property to convert "是" and "否" to the corresponding enum values.  
                        Isenable = row["是否冻结"].GetCString() == "是" ? StatusEnum.Enable : StatusEnum.Disable
                        #endregion
                    };
                    #region "校验必填项"

                    #endregion
                    //用唯一索引查询非重复
                    Expression<Func<EntranceAndexitEntity, bool>> whereExpression = whereExp =>
                        whereExp.Opening.Equals(importPosition.Opening);
                    var data = await _entranceAndexitEntity.GetFirstAsync(whereExpression);
                    if (data == null)
                    {
                        #region "自定义校验"

                        data = importPosition.Adapt(importPosition);
                        data.CreateOrgId = _userinfo.OrgId;
                        data.CreateUserName = _userinfo.RealName;
                        data.CreateUserId = _userinfo.UserId;
                        data.CreateTime = DateTime.Now; ;
                        #endregion

                        var rtAdd = await _entranceAndexitEntity.AsInsertable(data).ExecuteCommandAsync();
                        if (rtAdd != 1)
                        {
                            importPosition.ResultCode = 10004;
                            importPosition.Message = "插入失败";
                        }
                    }
                    else
                    {
                        #region "自定义校验"
                        data.UpdateUserId = _userinfo.UserId;
                        data.UpdateTime = DateTime.Now;
                        data.UpdateUserName = _userinfo.RealName;

                        #endregion
                        data.UpdateUserId = _userinfo.UserId;
                        data.UpdateUserName = _userinfo.RealName;
                        data.UpdateTime = DateTime.Now;

                        importPosition.Id = data.Id;

                        //不能用Adapt替换因为importPosition中没主键
                        //data = data.Adapt(importPosition, config);
                        data = importPosition.Adapt(data);


                        var rtUpdate = await _entranceAndexitEntity.AsUpdateable(data).ExecuteCommandAsync();
                        if (rtUpdate != 1)
                        {
                            importPosition.ResultCode = 10004;
                            importPosition.Message = "更新失败";
                        }
                    }

                    if (importPosition.ResultCode != 200)
                        listLoad.Add(importPosition);
                }

                // 返回导入失败数据
                if (listLoad.Count > 0)
                {
                    return listLoad;
                }
            }
            else
            {
                throw Oops.Oh(10002, "文件内容为空！");
            }
        }
        else
        {
            throw Oops.Oh(10002, "请选择文件！");
        }
        return null;
    }
}

